package com.tbs.parkingsaleapp.SystemManager.Handler.CallBacks;

import abstergo.tbs.betterasyc.Handler.IHandlerAction;
import android.os.Handler;
import android.os.Message;
import androidx.annotation.NonNull;
import com.tbs.parkingsaleapp.SystemManager.Handler.HandlerConst;

import java.util.HashMap;

public class ParkDataUpdater implements IHandlerAction {


    @Override
    public void Handle(Message msg) {
        switch (msg.arg2)
        {
            case HandlerConst.PARK_DATA_CALL:
                Call(msg.arg1);
                break;
            case HandlerConst.PARK_DATA_UPDATED:
                Updated(msg.arg1);
                delayhandler.sendMessageDelayed(delayMsg(msg.arg1),UPDATE_STATUS_DELAY);
                break;
        }
    }

    public interface IOnParkDataCall
    {
        void action(int location);
    }
    public interface IOnParkDataUpdated
    {
        void action(int location);
    }

    HashMap<String,IOnParkDataCall> callHashMap=new HashMap<>();
    HashMap<String,IOnParkDataUpdated>updatedHashMap=new HashMap<>();

    public ParkDataUpdater setCaller(String key,IOnParkDataCall caller) {
        if(callHashMap.containsKey(key))
            return this;

        callHashMap.put(key,caller);
        return this;
    }

    public ParkDataUpdater setUpdateder(String key,IOnParkDataUpdated updateder) {
        if(updatedHashMap.containsKey(key))
            return this;
        updatedHashMap.put(key,updateder);
        return this;
    }

    static ParkDataUpdater updater=new ParkDataUpdater();

    public static ParkDataUpdater Instance()
    {
        return updater;
    }
    private ParkDataUpdater()
    {

    }
    public static final int NOT_CALL = 760,UPDATING=777,UPDATED=780;
    StatusDelayer delayer=new StatusDelayer();
    Handler delayhandler=new Handler(delayer);
    HashMap<Integer,Integer> map=new HashMap<>();
    void Call(int location)
    {
        if(map.containsKey(location))
        {
            if(map.get(location)==UPDATED)
                throw new RuntimeException("过于频繁更新");

            if(map.get(location)!=NOT_CALL)
                throw new RuntimeException("错误调用更新请求");
        }
        map.put(location,UPDATING);
        for (IOnParkDataCall caller:callHashMap.values()
             ) {
            if(caller!=null)
                caller.action(location);
        }
    }
    void Updated(int location)
    {
        if(map.containsKey(location))
        {
            if(map.get(location)==UPDATING)
            {
                map.put(location,UPDATED);
                for (IOnParkDataUpdated updated:updatedHashMap.values()
                ) {
                    if(updated!=null)
                        updated.action(location);
                }
                return;
            }
        }
        throw new RuntimeException("错误调用更新完成请求");
    }

    void Reset(int location)
    {
        if(map.containsKey(location))
        {
            if(map.get(location)==UPDATED)
            {
                map.put(location,NOT_CALL);
                return;
            }

        }
        //throw new RuntimeException("错误重置");
    }

    public int getUpdatedResult(int location)
    {
        if(!map.containsKey(location))
            return NOT_CALL;
        return map.get(location);
    }

    public boolean CanUpdateNow(int location)
    {
        if(!map.containsKey(location))
            return true;
        return map.get(location)!=UPDATING;
    }
    public void NeedForUpdateNOW(int location)
    {
        if(CanUpdateNow(location))
        {
            Reset(location);
        }
    }

    public static Message msg_CallUpdate(int location)
    {
        Message ms=new Message();
        ms.what=HandlerConst.PARKDATAUPDATER;
        ms.arg2=HandlerConst.PARK_DATA_CALL;
        ms.arg1=location;
        return ms;
    }
    public static Message msg_Updated(int location)
    {
        Message ms=new Message();
        ms.what=HandlerConst.PARKDATAUPDATER;
        ms.arg2=HandlerConst.PARK_DATA_UPDATED;
        ms.arg1=location;
        return ms;
    }

    static Message delayMsg(int location)
    {
        Message ms=new Message();
        ms.what=HandlerConst.DATA_UPDATE_STATUS_DELAY;
        ms.arg1=location;
        return ms;
    }
    private static final int UPDATE_STATUS_DELAY =5*60*1000;

    class StatusDelayer implements Handler.Callback
    {
        @Override
        public boolean handleMessage(@NonNull Message msg) {
            if(msg.what== HandlerConst.DATA_UPDATE_STATUS_DELAY)
            {
                Reset(msg.arg1);
            }
            return false;
        }
    }

}